ஜாவாஸ்கிரிப்ட் கன்கரென்ட் கலெக்ஷன்களில் த்ரெட் பாதுகாப்பை ஆராயுங்கள். நம்பகமான செயல்திறனுக்காக த்ரெட்-பாதுகாப்பான தரவு கட்டமைப்புகள் மற்றும் கன்கரென்சி பேட்டர்ன்களைக் கொண்டு வலுவான பயன்பாடுகளை உருவாக்குவது எப்படி என்பதை அறியுங்கள்.
ஜாவாஸ்கிரிப்ட் கன்கரென்ட் கலெக்ஷன் த்ரெட் பாதுகாப்பு: த்ரெட்-பாதுகாப்பான தரவு கட்டமைப்புகளில் தேர்ச்சி பெறுதல்
ஜாவாஸ்கிரிப்ட் பயன்பாடுகள் சிக்கலானதாக வளரும்போது, திறமையான மற்றும் நம்பகமான கன்கரென்சி நிர்வாகத்தின் தேவை மிகவும் முக்கியமானதாகிறது. ஜாவாஸ்கிரிப்ட் பாரம்பரியமாக ஒரு சிங்கிள்-த்ரெட் மொழியாக இருந்தாலும், Node.js மற்றும் வெப் பிரவுசர்கள் போன்ற நவீன சூழல்கள் வெப் வொர்க்கர்கள் மற்றும் அசிங்க்ரோனஸ் செயல்பாடுகள் மூலம் கன்கரென்சிக்கான வழிமுறைகளை வழங்குகின்றன. இது பல த்ரெட்கள் அல்லது அசிங்க்ரோனஸ் பணிகள் பகிரப்பட்ட தரவை அணுகி மாற்றும்போது ரேஸ் கண்டிஷன்கள் மற்றும் தரவு சிதைவுக்கான வாய்ப்பை ஏற்படுத்துகிறது. இந்தக் கட்டுரை ஜாவாஸ்கிரிப்ட் கன்கரென்ட் கலெக்ஷன்களில் த்ரெட் பாதுகாப்பின் சவால்களை ஆராய்ந்து, வலுவான மற்றும் நம்பகமான பயன்பாடுகளை உருவாக்குவதற்கான நடைமுறை உத்திகளை வழங்குகிறது.
ஜாவாஸ்கிரிப்டில் கன்கரென்சியைப் புரிந்துகொள்ளுதல்
ஜாவாஸ்கிரிப்டின் ஈவென்ட் லூப் அசிங்க்ரோனஸ் புரோகிராமிங்கை செயல்படுத்துகிறது, இது மெயின் த்ரெட்டைத் தடுக்காமல் செயல்பாடுகளை இயக்க அனுமதிக்கிறது. இது கன்கரென்சியை வழங்கினாலும், மல்டி-த்ரெட் மொழிகளில் காணப்படும் உண்மையான பேரலலிசத்தை இது இயல்பாக வழங்குவதில்லை. இருப்பினும், வெப் வொர்க்கர்கள் ஜாவாஸ்கிரிப்ட் குறியீட்டை தனித்தனி த்ரெட்களில் இயக்க ஒரு வழியை வழங்குகின்றன, இது உண்மையான பேரலல் செயலாக்கத்தை செயல்படுத்துகிறது. இந்த திறன், மெயின் த்ரெட்டைத் தடுக்கும் கணக்கீட்டு ரீதியாக தீவிரமான பணிகளுக்கு மிகவும் மதிப்புமிக்கது, ஏனெனில் அது ஒரு மோசமான பயனர் அனுபவத்திற்கு வழிவகுக்கும்.
வெப் வொர்க்கர்கள்: மல்டித்ரெடிங்கிற்கு ஜாவாஸ்கிரிப்டின் பதில்
வெப் வொர்க்கர்கள் மெயின் த்ரெட்டிலிருந்து சுயாதீனமாக இயங்கும் பின்னணி ஸ்கிரிப்டுகள் ஆகும். அவை மெயின் த்ரெட்டுடன் ஒரு மெசேஜ்-பாஸிங் முறையைப் பயன்படுத்தி தொடர்பு கொள்கின்றன. இந்தத் தனிமைப்படுத்தல், ஒரு வெப் வொர்க்கரில் ஏற்படும் பிழைகள் அல்லது நீண்ட நேரம் இயங்கும் பணிகள் மெயின் த்ரெட்டின் பதிலளிக்கும் தன்மையை பாதிக்காது என்பதை உறுதி செய்கிறது. வெப் வொர்க்கர்கள் இமேஜ் பிராசஸிங், சிக்கலான கணக்கீடுகள் மற்றும் தரவு பகுப்பாய்வு போன்ற பணிகளுக்கு உகந்தவை.
அசிங்க்ரோனஸ் புரோகிராமிங் மற்றும் ஈவென்ட் லூப்
நெட்வொர்க் கோரிக்கைகள் மற்றும் ஃபைல் I/O போன்ற அசிங்க்ரோனஸ் செயல்பாடுகள் ஈவென்ட் லூப் மூலம் கையாளப்படுகின்றன. ஒரு அசிங்க்ரோனஸ் செயல்பாடு தொடங்கப்படும்போது, அது பிரவுசர் அல்லது Node.js ரன்டைமிடம் ஒப்படைக்கப்படுகிறது. செயல்பாடு முடிந்ததும், ஒரு கால்பேக் ஃபங்ஷன் ஈவென்ட் லூப் வரிசையில் வைக்கப்படுகிறது. மெயின் த்ரெட் கிடைக்கும்போது ஈவென்ட் லூப் அந்த கால்பேக்கை இயக்குகிறது. இந்த நான்-பிளாக்கிங் அணுகுமுறை ஜாவாஸ்கிரிப்ட் பயனர் இடைமுகத்தை முடக்காமல் ஒரே நேரத்தில் பல செயல்பாடுகளைக் கையாள அனுமதிக்கிறது.
த்ரெட் பாதுகாப்பின் சவால்கள்
த்ரெட் பாதுகாப்பு என்பது, பல த்ரெட்கள் ஒரே நேரத்தில் பகிரப்பட்ட தரவை அணுகும்போது கூட ஒரு புரோகிராம் சரியாக இயங்கும் திறனைக் குறிக்கிறது. ஒரு சிங்கிள்-த்ரெட் சூழலில், த்ரெட் பாதுகாப்பு பொதுவாக ஒரு கவலையாக இருப்பதில்லை, ஏனெனில் எந்த நேரத்திலும் ஒரே ஒரு செயல்பாடு மட்டுமே நிகழ முடியும். இருப்பினும், பல த்ரெட்கள் அல்லது அசிங்க்ரோனஸ் பணிகள் பகிரப்பட்ட தரவை அணுகி மாற்றும்போது, ரேஸ் கண்டிஷன்கள் ஏற்படலாம், இது கணிக்க முடியாத மற்றும் பேரழிவு விளைவுகளுக்கு வழிவகுக்கும். பல த்ரெட்கள் இயங்கும் கணிக்க முடியாத வரிசையைப் பொறுத்து ஒரு கணக்கீட்டின் முடிவு அமையும்போது ரேஸ் கண்டிஷன்கள் எழுகின்றன.
ரேஸ் கண்டிஷன்கள்: பிழைகளின் ஒரு பொதுவான மூலம்
பல த்ரெட்கள் ஒரே நேரத்தில் பகிரப்பட்ட தரவை அணுகி மாற்றும்போது, மற்றும் இறுதி முடிவு த்ரெட்கள் இயங்கும் குறிப்பிட்ட வரிசையைப் பொறுத்தது எனும்போது ஒரு ரேஸ் கண்டிஷன் ஏற்படுகிறது. இரண்டு த்ரெட்கள் ஒரு பகிரப்பட்ட கவுண்டரை அதிகரிக்கும் ஒரு எளிய உதாரணத்தைக் கவனியுங்கள்:
let counter = 0;
function incrementCounter() {
for (let i = 0; i < 100000; i++) {
counter++;
}
}
const worker1 = new Worker('worker.js');
const worker2 = new Worker('worker.js');
worker1.postMessage('start');
worker2.postMessage('start');
worker1.onmessage = function(event) {
console.log('Worker 1 finished');
};
worker2.onmessage = function(event) {
console.log('Worker 2 finished');
console.log('Final counter value:', counter);
};
// worker.js
self.onmessage = function(event) {
if (event.data === 'start') {
incrementCounter();
self.postMessage('done');
}
};
சிறந்தபட்சமாக, `counter`-ன் இறுதி மதிப்பு 200000 ஆக இருக்க வேண்டும். இருப்பினும், ரேஸ் கண்டிஷன் காரணமாக, உண்மையான மதிப்பு பெரும்பாலும் கணிசமாகக் குறைவாக இருக்கும். இதற்குக் காரணம், இரண்டு த்ரெட்களும் ஒரே நேரத்தில் `counter`-ஐப் படித்து எழுதுகின்றன, மேலும் அப்டேட்கள் கணிக்க முடியாத வழிகளில் ஒன்றோடொன்று கலக்கப்படலாம், இது இழந்த அப்டேட்களுக்கு வழிவகுக்கிறது.
தரவு சிதைவு: ஒரு கடுமையான விளைவு
ரேஸ் கண்டிஷன்கள் தரவு சிதைவுக்கு வழிவகுக்கும், இதில் பகிரப்பட்ட தரவு சீரற்றதாக அல்லது செல்லாததாக மாறும். இது கடுமையான விளைவுகளை ஏற்படுத்தும், குறிப்பாக நிதி அமைப்புகள், மருத்துவ சாதனங்கள் மற்றும் கட்டுப்பாட்டு அமைப்புகள் போன்ற துல்லியமான தரவை நம்பியிருக்கும் பயன்பாடுகளில். தரவு சிதைவைக் கண்டறிந்து சரிசெய்வது கடினமாக இருக்கும், ஏனெனில் அதன் அறிகுறிகள் இடைப்பட்டதாகவும் கணிக்க முடியாததாகவும் இருக்கலாம்.
ஜாவாஸ்கிரிப்டில் த்ரெட்-பாதுகாப்பான தரவு கட்டமைப்புகள்
ரேஸ் கண்டிஷன்கள் மற்றும் தரவு சிதைவின் அபாயங்களைக் குறைக்க, த்ரெட்-பாதுகாப்பான தரவு கட்டமைப்புகள் மற்றும் கன்கரென்சி பேட்டர்ன்களைப் பயன்படுத்துவது அவசியம். த்ரெட்-பாதுகாப்பான தரவு கட்டமைப்புகள், பகிரப்பட்ட தரவிற்கான கன்கரென்ட் அணுகல் ஒத்திசைக்கப்படுவதையும், தரவு ஒருமைப்பாடு பராமரிக்கப்படுவதையும் உறுதிசெய்ய வடிவமைக்கப்பட்டுள்ளன. சில பிற மொழிகளைப் போல (ஜாவாவின் `ConcurrentHashMap` போன்றவை) ஜாவாஸ்கிரிப்டில் உள்ளமைக்கப்பட்ட த்ரெட்-பாதுகாப்பான தரவு கட்டமைப்புகள் இல்லை என்றாலும், த்ரெட் பாதுகாப்பை அடைய நீங்கள் பயன்படுத்தக்கூடிய பல உத்திகள் உள்ளன.
அட்டாமிக் செயல்பாடுகள்
அட்டாமிக் செயல்பாடுகள் என்பவை ஒரே, பிரிக்க முடியாத அலகாக செயல்படுத்தப்படும் என்று உத்தரவாதம் அளிக்கப்பட்ட செயல்பாடுகள் ஆகும். இதன் பொருள், ஒரு அட்டாமிக் செயல்பாடு செயல்பாட்டில் இருக்கும்போது வேறு எந்த த்ரெட்டும் அதை குறுக்கிட முடியாது. அட்டாமிக் செயல்பாடுகள் த்ரெட்-பாதுகாப்பான தரவு கட்டமைப்புகள் மற்றும் கன்கரென்சி கட்டுப்பாட்டிற்கான ஒரு அடிப்படைக் கட்டுமானத் தொகுதி ஆகும். ஜாவாஸ்கிரிப்ட் SharedArrayBuffer API-யின் ஒரு பகுதியான `Atomics` ஆப்ஜெக்ட் மூலம் அட்டாமிக் செயல்பாடுகளுக்கு வரையறுக்கப்பட்ட ஆதரவை வழங்குகிறது.
SharedArrayBuffer
`SharedArrayBuffer` என்பது ஒரு தரவுக் கட்டமைப்பாகும், இது பல வெப் வொர்க்கர்களை ஒரே நினைவகத்தை அணுகவும் மாற்றவும் அனுமதிக்கிறது. இது த்ரெட்களுக்கு இடையில் திறமையான தரவுப் பகிர்வை செயல்படுத்துகிறது, ஆனால் இது ரேஸ் கண்டிஷன்களுக்கான வாய்ப்பையும் அறிமுகப்படுத்துகிறது. `Atomics` ஆப்ஜெக்ட், ஒரு `SharedArrayBuffer`-ல் உள்ள தரவைப் பாதுகாப்பாகக் கையாளப் பயன்படுத்தக்கூடிய அட்டாமிக் செயல்பாடுகளின் தொகுப்பை வழங்குகிறது.
Atomics API
`Atomics` API பல்வேறு அட்டாமிக் செயல்பாடுகளை வழங்குகிறது, அவற்றுள் சில:
- `Atomics.add(typedArray, index, value)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள உறுப்புடன் ஒரு மதிப்பை அட்டாமிக் முறையில் சேர்க்கிறது.
- `Atomics.sub(typedArray, index, value)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள உறுப்பிலிருந்து ஒரு மதிப்பைக் அட்டாமிக் முறையில் கழிக்கிறது.
- `Atomics.and(typedArray, index, value)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள உறுப்பில் ஒரு பிட்வைஸ் AND செயல்பாட்டை அட்டாமிக் முறையில் செய்கிறது.
- `Atomics.or(typedArray, index, value)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள உறுப்பில் ஒரு பிட்வைஸ் OR செயல்பாட்டை அட்டாமிக் முறையில் செய்கிறது.
- `Atomics.xor(typedArray, index, value)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள உறுப்பில் ஒரு பிட்வைஸ் XOR செயல்பாட்டை அட்டாமிக் முறையில் செய்கிறது.
- `Atomics.exchange(typedArray, index, value)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள உறுப்பை ஒரு புதிய மதிப்புடன் அட்டாமிக் முறையில் மாற்றி, பழைய மதிப்பைத் திருப்பித் தருகிறது.
- `Atomics.compareExchange(typedArray, index, expectedValue, newValue)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள உறுப்பை ஒரு எதிர்பார்க்கப்படும் மதிப்புடன் அட்டாமிக் முறையில் ஒப்பிடுகிறது. அவை சமமாக இருந்தால், உறுப்பு ஒரு புதிய மதிப்புடன் மாற்றப்படுகிறது. அசல் மதிப்பைத் திருப்பித் தருகிறது.
- `Atomics.load(typedArray, index)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள மதிப்பை அட்டாமிக் முறையில் ஏற்றுகிறது.
- `Atomics.store(typedArray, index, value)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் ஒரு மதிப்பை அட்டாமிக் முறையில் சேமிக்கிறது.
- `Atomics.wait(typedArray, index, value, timeout)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள மதிப்பு மாறும் வரை அல்லது காலக்கெடு முடியும் வரை தற்போதைய த்ரெட்டைத் தடுக்கிறது.
- `Atomics.notify(typedArray, index, count)`: ஒரு டைப்டு அரேயில் குறிப்பிட்ட இன்டெக்ஸில் உள்ள மதிப்புக்காகக் காத்திருக்கும் குறிப்பிட்ட எண்ணிக்கையிலான த்ரெட்களை எழுப்புகிறது.
ஒரு த்ரெட்-பாதுகாப்பான கவுண்டரை செயல்படுத்த `Atomics.add` ஐப் பயன்படுத்துவதற்கான ஒரு எடுத்துக்காட்டு இங்கே:
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const counter = new Int32Array(sab);
function incrementCounter() {
for (let i = 0; i < 100000; i++) {
Atomics.add(counter, 0, 1);
}
}
const worker1 = new Worker('worker.js');
const worker2 = new Worker('worker.js');
worker1.postMessage('start');
worker2.postMessage('start');
worker1.onmessage = function(event) {
console.log('Worker 1 finished');
};
worker2.onmessage = function(event) {
console.log('Worker 2 finished');
console.log('Final counter value:', Atomics.load(counter, 0));
};
// worker.js
self.onmessage = function(event) {
if (event.data === 'start') {
incrementCounter();
self.postMessage('done');
}
};
இந்த எடுத்துக்காட்டில், `counter` ஒரு `SharedArrayBuffer`-ல் சேமிக்கப்படுகிறது, மேலும் `Atomics.add` கவுண்டரை அட்டாமிக் முறையில் அதிகரிக்கப் பயன்படுத்தப்படுகிறது. இது பல த்ரெட்கள் ஒரே நேரத்தில் அதை அதிகரிக்கும்போதும், `counter`-ன் இறுதி மதிப்பு எப்போதும் 200000 ஆக இருப்பதை உறுதி செய்கிறது.
லாக்குகள் மற்றும் செமாஃபோர்கள்
லாக்குகள் மற்றும் செமாஃபோர்கள் பகிரப்பட்ட வளங்களுக்கான அணுகலைக் கட்டுப்படுத்தப் பயன்படும் ஒத்திசைவுப் பிரிமிட்டிவ்கள் ஆகும். ஒரு லாக் (மியூடெக்ஸ் என்றும் அழைக்கப்படுகிறது) ஒரே நேரத்தில் ஒரு த்ரெட் மட்டுமே பகிரப்பட்ட வளத்தை அணுக அனுமதிக்கிறது, அதே நேரத்தில் ஒரு செமாஃபோர் வரையறுக்கப்பட்ட எண்ணிக்கையிலான த்ரெட்களை ஒரே நேரத்தில் ஒரு பகிரப்பட்ட வளத்தை அணுக அனுமதிக்கிறது.
Atomics உடன் லாக்குகளை செயல்படுத்துதல்
`Atomics.compareExchange` மற்றும் `Atomics.wait`/`Atomics.notify` செயல்பாடுகளைப் பயன்படுத்தி லாக்குகளைச் செயல்படுத்தலாம். ஒரு எளிய லாக் செயல்பாட்டிற்கான எடுத்துக்காட்டு இங்கே:
class Lock {
constructor() {
this.sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
this.lock = new Int32Array(this.sab);
this.UNLOCKED = 0;
this.LOCKED = 1;
}
lockAcquire() {
while (Atomics.compareExchange(this.lock, 0, this.UNLOCKED, this.LOCKED) !== this.UNLOCKED) {
Atomics.wait(this.lock, 0, this.LOCKED, Number.POSITIVE_INFINITY); // Wait until unlocked
}
}
lockRelease() {
Atomics.store(this.lock, 0, this.UNLOCKED);
Atomics.notify(this.lock, 0, 1); // Wake up one waiting thread
}
}
// Usage
const lock = new Lock();
function criticalSection() {
lock.lockAcquire();
try {
// Access shared resources safely here
console.log('Critical section entered');
// Simulate some work
for (let i = 0; i < 1000; i++) {}
} finally {
lock.lockRelease();
console.log('Critical section exited');
}
}
const worker1 = new Worker('worker.js');
const worker2 = new Worker('worker.js');
worker1.postMessage({ action: 'start', lockSab: lock.sab });
worker2.postMessage({ action: 'start', lockSab: lock.sab });
// worker.js
let lock;
class Lock {
constructor(sab) {
this.sab = sab;
this.lock = new Int32Array(this.sab);
this.UNLOCKED = 0;
this.LOCKED = 1;
}
lockAcquire() {
while (Atomics.compareExchange(this.lock, 0, this.UNLOCKED, this.LOCKED) !== this.UNLOCKED) {
Atomics.wait(this.lock, 0, this.LOCKED, Number.POSITIVE_INFINITY);
}
}
lockRelease() {
Atomics.store(this.lock, 0, this.UNLOCKED);
Atomics.notify(this.lock, 0, 1);
}
}
self.onmessage = function(event) {
if (event.data.action === 'start') {
lock = new Lock(event.data.lockSab);
for (let i = 0; i < 5; i++) {
criticalSection();
}
}
function criticalSection() {
lock.lockAcquire();
try {
console.log('Worker ' + self.name + ': Critical section entered');
} finally {
lock.lockRelease();
console.log('Worker ' + self.name + ': Critical section exited');
}
}
};
பகிரப்பட்ட வளங்களை கன்கரென்ட் அணுகலில் இருந்து பாதுகாக்கப் பயன்படும் ஒரு எளிய லாக்கைச் செயல்படுத்த `Atomics`-ஐ எப்படிப் பயன்படுத்துவது என்பதை இந்த எடுத்துக்காட்டு விளக்குகிறது. `lockAcquire` முறை `Atomics.compareExchange`-ஐப் பயன்படுத்தி லாக்கைப் பெற முயற்சிக்கிறது. லாக் ஏற்கனவே பிடிக்கப்பட்டிருந்தால், லாக் விடுவிக்கப்படும் வரை த்ரெட் `Atomics.wait`-ஐப் பயன்படுத்தி காத்திருக்கிறது. `lockRelease` முறை, லாக் மதிப்பை `UNLOCKED` என அமைத்து, `Atomics.notify`-ஐப் பயன்படுத்தி காத்திருக்கும் த்ரெட்டிற்கு அறிவிப்பதன் மூலம் லாக்கை விடுவிக்கிறது.
செமாஃபோர்கள்
செமாஃபோர் என்பது லாக்கை விட ஒரு பொதுவான ஒத்திசைவுப் பிரிமிட்டிவ் ஆகும். இது கிடைக்கக்கூடிய வளங்களின் எண்ணிக்கையைக் குறிக்கும் ஒரு எண்ணிக்கையைப் பராமரிக்கிறது. த்ரெட்கள் எண்ணிக்கையைக் குறைப்பதன் மூலம் ஒரு வளத்தைப் பெறலாம், மேலும் எண்ணிக்கையை அதிகரிப்பதன் மூலம் ஒரு வளத்தை விடுவிக்கலாம். செமாஃபோர்கள் ஒரே நேரத்தில் வரையறுக்கப்பட்ட எண்ணிக்கையிலான பகிரப்பட்ட வளங்களுக்கான அணுகலைக் கட்டுப்படுத்தப் பயன்படுத்தப்படலாம்.
இம்யூட்டபிலிட்டி (மாற்ற இயலாமை)
இம்யூட்டபிலிட்டி என்பது ஒரு புரோகிராமிங் முன்னுதாரணமாகும், இது உருவாக்கப்பட்ட பிறகு மாற்ற முடியாத ஆப்ஜெக்ட்களை உருவாக்குவதை வலியுறுத்துகிறது. தரவு மாற்ற முடியாததாக இருக்கும்போது, ரேஸ் கண்டிஷன்களுக்கு ஆபத்து இல்லை, ஏனெனில் பல த்ரெட்கள் சிதைவு பயமின்றி தரவைப் பாதுகாப்பாக அணுக முடியும். ஜாவாஸ்கிரிப்ட் `const` மாறிகள் மற்றும் இம்யூட்டபிள் தரவுக் கட்டமைப்புகளின் பயன்பாட்டின் மூலம் இம்யூட்டபிலிட்டியை ஆதரிக்கிறது.
இம்யூட்டபிள் தரவுக் கட்டமைப்புகள்
Immutable.js போன்ற லைப்ரரிகள் லிஸ்ட்கள், மேப்கள் மற்றும் செட்கள் போன்ற இம்யூட்டபிள் தரவுக் கட்டமைப்புகளை வழங்குகின்றன. இந்த தரவுக் கட்டமைப்புகள், தரவு ஒருபோதும் அதன் இடத்தில் மாற்றப்படவில்லை என்பதை உறுதிசெய்யும் அதே வேளையில், திறமையாகவும் செயல்திறன் மிக்கதாகவும் வடிவமைக்கப்பட்டுள்ளன. மாறாக, இம்யூட்டபிள் தரவுக் கட்டமைப்புகளில் உள்ள செயல்பாடுகள், புதுப்பிக்கப்பட்ட தரவுடன் புதிய இன்ஸ்டன்ஸ்களைத் திருப்பித் தருகின்றன.
const { Map, List } = require('immutable');
let myMap = Map({ a: 1, b: 2, c: 3 });
// Modifying the map returns a new map
let updatedMap = myMap.set('b', 4);
console.log(myMap.toJS()); // { a: 1, b: 2, c: 3 }
console.log(updatedMap.toJS()); // { a: 1, b: 4, c: 3 }
let myList = List([1, 2, 3]);
let updatedList = myList.push(4);
console.log(myList.toJS()); // [ 1, 2, 3 ]
console.log(updatedList.toJS()); // [ 1, 2, 3, 4 ]
இம்யூட்டபிள் தரவுக் கட்டமைப்புகளைப் பயன்படுத்துவது கன்கரென்சி நிர்வாகத்தை கணிசமாக எளிதாக்கும், ஏனெனில் பகிரப்பட்ட தரவிற்கான அணுகலை ஒத்திசைப்பது பற்றி நீங்கள் கவலைப்படத் தேவையில்லை. இருப்பினும், புதிய இம்யூட்டபிள் ஆப்ஜெக்ட்களை உருவாக்குவது செயல்திறன் மேல்சுமையைக் கொண்டிருக்கக்கூடும் என்பதை அறிந்திருப்பது முக்கியம், குறிப்பாக பெரிய தரவுக் கட்டமைப்புகளுக்கு. எனவே, இம்யூட்டபிலிட்டியின் நன்மைகளை சாத்தியமான செயல்திறன் செலவுகளுக்கு எதிராக எடைபோடுவது முக்கியம்.
மெசேஜ் பாஸிங் (செய்தி அனுப்புதல்)
மெசேஜ் பாஸிங் என்பது ஒரு கன்கரென்சி பேட்டர்ன் ஆகும், இதில் த்ரெட்கள் ஒன்றுக்கொன்று மெசேஜ்களை அனுப்புவதன் மூலம் தொடர்பு கொள்கின்றன. தரவை நேரடியாகப் பகிர்வதற்குப் பதிலாக, த்ரெட்கள் மெசேஜ்கள் மூலம் தகவல்களைப் பரிமாறிக்கொள்கின்றன, அவை பொதுவாக நகலெடுக்கப்படுகின்றன அல்லது வரிசைப்படுத்தப்படுகின்றன. இது பகிரப்பட்ட நினைவகம் மற்றும் ஒத்திசைவுப் பிரிமிட்டிவ்களின் தேவையை நீக்குகிறது, இது கன்கரென்சியைப் பற்றி பகுத்தாய்வதையும் ரேஸ் கண்டிஷன்களைத் தவிர்ப்பதையும் எளிதாக்குகிறது. ஜாவாஸ்கிரிப்டில் உள்ள வெப் வொர்க்கர்கள் மெயின் த்ரெட் மற்றும் வொர்க்கர் த்ரெட்களுக்கு இடையேயான தகவல்தொடர்புக்கு மெசேஜ் பாஸிங்கை நம்பியுள்ளன.
வெப் வொர்க்கர் தகவல்தொடர்பு
முந்தைய எடுத்துக்காட்டுகளில் காணப்பட்டபடி, வெப் வொர்க்கர்கள் `postMessage` முறை மற்றும் `onmessage` ஈவென்ட் ஹேண்ட்லரைப் பயன்படுத்தி மெயின் த்ரெட்டுடன் தொடர்பு கொள்கின்றன. இந்த மெசேஜ்-பாஸிங் வழிமுறை, பகிரப்பட்ட நினைவகத்துடன் தொடர்புடைய அபாயங்கள் இல்லாமல் த்ரெட்களுக்கு இடையில் தரவைப் பரிமாறிக்கொள்ள ஒரு சுத்தமான மற்றும் பாதுகாப்பான வழியை வழங்குகிறது. இருப்பினும், த்ரெட்களுக்கு இடையில் அனுப்பப்படும்போது தரவு வரிசைப்படுத்தப்பட்டு, மீண்டும் மாற்றப்பட வேண்டியிருப்பதால், மெசேஜ் பாஸிங் தாமதம் மற்றும் மேல்சுமையை அறிமுகப்படுத்தக்கூடும் என்பதை அறிந்திருப்பது முக்கியம்.
ஆக்டர் மாடல்
ஆக்டர் மாடல் என்பது ஒரு கன்கரென்சி மாடல் ஆகும், இதில் கணக்கீடு ஆக்டர்களால் செய்யப்படுகிறது, அவை அசிங்க்ரோனஸ் மெசேஜ் பாஸிங் மூலம் ஒன்றுக்கொன்று தொடர்பு கொள்ளும் சுயாதீனமான সত্তைகள். ஒவ்வொரு ஆக்டருக்கும் அதன் சொந்த நிலை உள்ளது, மேலும் உள்வரும் மெசேஜ்களுக்குப் பதிலளிக்கும் வகையில் அதன் சொந்த நிலையை மட்டுமே மாற்ற முடியும். இந்த நிலையின் தனிமைப்படுத்தல், லாக்குகள் மற்றும் பிற ஒத்திசைவுப் பிரிமிட்டிவ்களின் தேவையை நீக்குகிறது, இது கன்கரென்ட் மற்றும் விநியோகிக்கப்பட்ட அமைப்புகளை உருவாக்குவதை எளிதாக்குகிறது.
ஆக்டர் லைப்ரரிகள்
ஜாவாஸ்கிரிப்டில் ஆக்டர் மாடலுக்கு உள்ளமைக்கப்பட்ட ஆதரவு இல்லை என்றாலும், பல லைப்ரரிகள் இந்த பேட்டர்னை செயல்படுத்துகின்றன. இந்த லைப்ரரிகள் ஆக்டர்களை உருவாக்குவதற்கும் நிர்வகிப்பதற்கும், ஆக்டர்களுக்கு இடையில் மெசேஜ்களை அனுப்புவதற்கும், அசிங்க்ரோனஸ் ஈவென்ட்களைக் கையாளுவதற்கும் ஒரு கட்டமைப்பை வழங்குகின்றன. ஆக்டர் மாடல் மிகவும் கன்கரென்ட் மற்றும் அளவிடக்கூடிய பயன்பாடுகளை உருவாக்குவதற்கான ஒரு சக்திவாய்ந்த கருவியாக இருக்க முடியும், ஆனால் இது புரோகிராம் வடிவமைப்பைப் பற்றி வித்தியாசமான முறையில் சிந்திக்கவும் தேவைப்படுகிறது.
ஜாவாஸ்கிரிப்டில் த்ரெட் பாதுகாப்பிற்கான சிறந்த நடைமுறைகள்
த்ரெட்-பாதுகாப்பான ஜாவாஸ்கிரிப்ட் பயன்பாடுகளை உருவாக்க கவனமான திட்டமிடல் மற்றும் விவரங்களுக்கு கவனம் தேவை. பின்பற்ற வேண்டிய சில சிறந்த நடைமுறைகள் இங்கே:
- பகிரப்பட்ட நிலையை குறைக்கவும்: பகிரப்பட்ட நிலை எவ்வளவு குறைவாக உள்ளதோ, அவ்வளவு குறைவாக ரேஸ் கண்டிஷன்களின் ஆபத்து இருக்கும். தனிப்பட்ட த்ரெட்கள் அல்லது ஆக்டர்களுக்குள் நிலையை உள்ளடக்க முயற்சிக்கவும், மற்றும் மெசேஜ் பாஸிங் மூலம் தொடர்பு கொள்ளவும்.
- முடிந்தவரை அட்டாமிக் செயல்பாடுகளைப் பயன்படுத்தவும்: பகிரப்பட்ட நிலை தவிர்க்க முடியாததாக இருக்கும்போது, தரவு பாதுகாப்பாக மாற்றப்படுவதை உறுதிசெய்ய அட்டாமிக் செயல்பாடுகளைப் பயன்படுத்தவும்.
- இம்யூட்டபிலிட்டியைக் கருத்தில் கொள்ளுங்கள்: இம்யூட்டபிலிட்டி ஒத்திசைவுப் பிரிமிட்டிவ்களின் தேவையை முற்றிலுமாக நீக்கி, கன்கரென்சியைப் பற்றி பகுத்தாய்வதை எளிதாக்கும்.
- லாக்குகள் மற்றும் செமாஃபோர்களை குறைவாகப் பயன்படுத்தவும்: லாக்குகள் மற்றும் செமாஃபோர்கள் செயல்திறன் மேல்சுமை மற்றும் சிக்கலை அறிமுகப்படுத்தலாம். தேவைப்படும்போது மட்டுமே அவற்றைப் பயன்படுத்தவும், மேலும் டெட்லாக்குகளைத் தவிர்க்க அவை சரியாகப் பயன்படுத்தப்படுவதை உறுதிசெய்யவும்.
- முழுமையாகச் சோதிக்கவும்: ரேஸ் கண்டிஷன்கள் மற்றும் பிற கன்கரென்சி தொடர்பான பிழைகளைக் கண்டறிந்து சரிசெய்ய உங்கள் கன்கரென்ட் குறியீட்டை முழுமையாகச் சோதிக்கவும். அதிக சுமை சூழ்நிலைகளை உருவகப்படுத்தவும், சாத்தியமான சிக்கல்களை வெளிப்படுத்தவும் கன்கரென்சி ஸ்ட்ரெஸ் டெஸ்ட்கள் போன்ற கருவிகளைப் பயன்படுத்தவும்.
- குறியீட்டுத் தரங்களைப் பின்பற்றவும்: உங்கள் கன்கரென்ட் குறியீட்டின் வாசிப்புத்திறன் மற்றும் பராமரிப்புத்தன்மையை மேம்படுத்த குறியீட்டுத் தரங்கள் மற்றும் சிறந்த நடைமுறைகளைக் கடைப்பிடிக்கவும்.
- லின்டர்கள் மற்றும் ஸ்டேடிக் அனாலிசிஸ் கருவிகளைப் பயன்படுத்தவும்: மேம்பாட்டு செயல்முறையின் ஆரம்பத்தில் சாத்தியமான கன்கரென்சி சிக்கல்களைக் கண்டறிய லின்டர்கள் மற்றும் ஸ்டேடிக் அனாலிசிஸ் கருவிகளைப் பயன்படுத்தவும்.
நிஜ-உலக எடுத்துக்காட்டுகள்
பல்வேறு நிஜ-உலக ஜாவாஸ்கிரிப்ட் பயன்பாடுகளில் த்ரெட் பாதுகாப்பு மிகவும் முக்கியமானது:
- வெப் சர்வர்கள்: Node.js வெப் சர்வர்கள் பல கன்கரென்ட் கோரிக்கைகளைக் கையாளுகின்றன. தரவு ஒருமைப்பாட்டைப் பராமரிக்கவும், செயலிழப்புகளைத் தடுக்கவும் த்ரெட் பாதுகாப்பை உறுதி செய்வது முக்கியம். உதாரணமாக, ஒரு சர்வர் பயனர் செஷன் தரவை நிர்வகித்தால், செஷன் ஸ்டோருக்கான கன்கரென்ட் அணுகல் கவனமாக ஒத்திசைக்கப்பட வேண்டும்.
- ரியல்-டைம் பயன்பாடுகள்: அரட்டை சர்வர்கள் மற்றும் ஆன்லைன் கேம்கள் போன்ற பயன்பாடுகளுக்கு குறைந்த தாமதம் மற்றும் அதிக செயல்திறன் தேவை. கன்கரென்ட் இணைப்புகளைக் கையாளுவதற்கும், கேம் நிலையைப் புதுப்பிப்பதற்கும் த்ரெட் பாதுகாப்பு அவசியம்.
- தரவு செயலாக்கம்: இமேஜ் எடிட்டிங் அல்லது வீடியோ என்கோடிங் போன்ற தரவு செயலாக்கத்தைச் செய்யும் பயன்பாடுகள் கன்கரென்சியால் பயனடையலாம். தரவு சரியாகச் செயலாக்கப்படுவதையும், முடிவுகள் சீராக இருப்பதையும் உறுதிசெய்ய த்ரெட் பாதுகாப்பு அவசியம்.
- அறிவியல் கணினி: அறிவியல் பயன்பாடுகள் பெரும்பாலும் வெப் வொர்க்கர்களைப் பயன்படுத்தி பேரலலைஸ் செய்யக்கூடிய சிக்கலான கணக்கீடுகளை உள்ளடக்கியது. இந்தக் கணக்கீடுகளின் முடிவுகள் துல்லியமானவை என்பதை உறுதிசெய்ய த்ரெட் பாதுகாப்பு முக்கியமானது.
- நிதி அமைப்புகள்: நிதிப் பயன்பாடுகளுக்கு அதிக துல்லியம் மற்றும் நம்பகத்தன்மை தேவை. தரவு சிதைவைத் தடுக்கவும், பரிவர்த்தனைகள் சரியாகச் செயலாக்கப்படுவதை உறுதிசெய்யவும் த்ரெட் பாதுகாப்பு அவசியம். உதாரணமாக, பல பயனர்கள் ஒரே நேரத்தில் ஆர்டர்களை வைக்கும் ஒரு பங்கு வர்த்தக தளத்தைக் கவனியுங்கள்.
முடிவுரை
த்ரெட் பாதுகாப்பு என்பது வலுவான மற்றும் நம்பகமான ஜாவாஸ்கிரிப்ட் பயன்பாடுகளை உருவாக்குவதில் ஒரு முக்கிய அம்சமாகும். ஜாவாஸ்கிரிப்டின் சிங்கிள்-த்ரெட் தன்மை பல கன்கரென்சி சிக்கல்களை எளிதாக்கினாலும், வெப் வொர்க்கர்கள் மற்றும் அசிங்க்ரோனஸ் புரோகிராமிங்கின் அறிமுகம் ஒத்திசைவு மற்றும் தரவு ஒருமைப்பாட்டிற்கு கவனமான கவனம் தேவைப்படுகிறது. த்ரெட் பாதுகாப்பின் சவால்களைப் புரிந்துகொண்டு, பொருத்தமான கன்கரென்சி பேட்டர்ன்கள் மற்றும் தரவுக் கட்டமைப்புகளைப் பயன்படுத்துவதன் மூலம், டெவலப்பர்கள் ரேஸ் கண்டிஷன்கள் மற்றும் தரவு சிதைவுக்கு எதிர்ப்புத் தெரிவிக்கும் மிகவும் கன்கரென்ட் மற்றும் அளவிடக்கூடிய பயன்பாடுகளை உருவாக்க முடியும். இம்யூட்டபிலிட்டியை ஏற்றுக்கொள்வது, அட்டாமிக் செயல்பாடுகளைப் பயன்படுத்துவது மற்றும் பகிரப்பட்ட நிலையை கவனமாக நிர்வகிப்பது ஆகியவை ஜாவாஸ்கிரிப்டில் த்ரெட் பாதுகாப்பில் தேர்ச்சி பெறுவதற்கான முக்கிய உத்திகள் ஆகும்.
ஜாவாஸ்கிரிப்ட் தொடர்ந்து வளர்ச்சியடைந்து மேலும் கன்கரென்சி அம்சங்களை ஏற்றுக்கொள்வதால், த்ரெட் பாதுகாப்பின் முக்கியத்துவம் மட்டுமே அதிகரிக்கும். சமீபத்திய நுட்பங்கள் மற்றும் சிறந்த நடைமுறைகள் குறித்துத் தெரிந்துகொள்வதன் மூலம், டெவலப்பர்கள் தங்கள் பயன்பாடுகள் அதிகரித்து வரும் சிக்கல்களுக்கு மத்தியிலும் வலுவானதாகவும், நம்பகமானதாகவும், செயல்திறன் மிக்கதாகவும் இருப்பதை உறுதிசெய்ய முடியும்.